package com.example.wxy.bbtapp.Common.FileTransfer;

import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

/**
 * Created by songxiaolin on 2017/9/17.
 */

public class FileTransport {
    /**
     * 有文件下载的指令后，客户端去服务器要文件
     * 服务器判断跟这个客户端一起的有没有别的机子，如果有，而且他已经下载过了，就给客户端发送这个机子的ip和端口
     * 客户端拿到ip信息后就去另一个客户端要文件进行传输
     *
     * 如果没有别的机子有文件，服务器就给客户端文件（通过webapi给地址，然后自行下载）
     *
     *
     *
     * 文件发送函数，多个文件依次发送，首先发送文件名，对方接收后，在发送文件内容
     * @param
     */

    private  int bufferSize=256;
    private int numLength;
    private int PORT;
    private TransportCallback _callback;

    public FileTransport(TransportCallback callback)
    {
        _callback = callback;
    }

    public  interface TransportCallback{
        public void onReceived(int progress);
        public  void onSended(int progress);
    }

    Handler handler = new Handler(){
        public void handleMessage(Message msg) {

            if(_callback == null)
            return;

            switch (msg.what) {
                case 11:
                    _callback.onReceived(msg.arg1);
                    break;
                case 10:
                    _callback.onSended(msg.arg1);
                    break;
            }
            super.handleMessage(msg);
        }

    };

    public void startSendFile(final String senderIP,final ArrayList<FileName> tempFiles)
    {
        final byte[] filesendhenad=new byte[bufferSize];
        for(int i=0;i<bufferSize;i++)
        {
            filesendhenad[i]=0;
        }
        for(final FileName file:tempFiles)
        {
            File f=new File(file.getFullPath());
            numLength+=f.length();

        }

        new Thread()
        {
            @Override
            public void run()
            {
                Socket socket=null;
                OutputStream output=null;
                InputStream input=null;
                try {
                    for(final FileName files:tempFiles)//多线程发送文件
                    {
                        //首先发送文件名，然后发送文件内容
                        socket=new Socket(senderIP,PORT);
                        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$abc");
                        byte[] filenamebytes=files.getFileName().getBytes();
                        System.arraycopy(filenamebytes, 0, filesendhenad, 16, filenamebytes.length);
                        output=socket.getOutputStream();  //构建一个输出流
                        output.write(filesendhenad);   //把头数据包发送给对方
                        output.flush();
                        sleep(1000);  //sleep1秒，等待对方处理


                        //读取文件并发送
                        byte[] readbuffer=new byte[bufferSize];
                        input=new FileInputStream(new File(files.fileName));
                        int readSize = 0;
                        int length =0;
                        long count = 0;
                        while(-1!=(readSize=input.read(readbuffer)))
                        {
                            output.write(readbuffer,0,readSize);
                            output.flush();
                            length+=readSize;
                            int progress=((int)((Float.valueOf(length)/Float.valueOf(numLength))*100));
                            Message message=new Message();
                            message.what=10;
                            message.arg1=progress;
                            handler.sendMessage(message);//此处的Message用于更新UI

                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }finally{
                    try {
                        if(null!=output)output.close();
                        if(null!=input)input.close();
                        if(!socket.isClosed())socket.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }}

            };
        }.start();
    }


    /**
     * 文件接收Thread，首先接受文件名，包含更新进度条的操作
     * @author paulwang
     *
     */
    public class TCPReceiveFileThread extends Thread {
        final static public int buffersize = 256;
        final static public int ServerPort = 8092;
        private ServerSocket sSocket = null;
        private int mlength=0;
        String savePath = "";

        public TCPReceiveFileThread() {
            savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyWIFIRec/";
            //判断接收文件的文件夹是否存在，若不存在，则创建
            File fileDir = new File(savePath);
            if (!fileDir.exists()) {    //若不存在
                fileDir.mkdir();
            }
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub

            super.run();
            try {
                sSocket = new ServerSocket(ServerPort);
                System.out.println("FileReceiveThread socket started ...");
                while (!sSocket.isClosed() && null != sSocket) {
                    Socket socket = sSocket.accept();
                    socket.setSoTimeout(5000);
                    new SaveFileToDisk(socket).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public class SaveFileToDisk extends Thread {
            private Socket socket = null;


            public SaveFileToDisk(Socket socket) {
                this.socket = socket;
            }



            @Override
            public void run() {
                // TODO Auto-generated method stub
                super.run();
                OutputStream output = null;
                InputStream input = null;
                try {

                    byte[] filenamehead = new byte[buffersize];//接收对方第一次发过来的数据，该数据包中包含了要发送的文件名
                    input = socket.getInputStream();
                    input.read(filenamehead);
                    byte[] fileNameBytes = new byte[buffersize];
                    System.arraycopy(filenamehead, 0, fileNameBytes, 0, buffersize);
                    String fname = new String(fileNameBytes).trim();
                    System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$!!!!!!!!!!!!!" + fname);
                    StringBuffer sb = new StringBuffer();
                    sb.append(savePath).append(fname);
                    String filename = sb.toString();
                    File file = new File(filename);


                    byte[] readbuffer = new byte[buffersize];
                    output = new FileOutputStream(file);
                    int readSize = 0;
                    while (-1 != (readSize = input.read(readbuffer))) {
                        output.write(readbuffer, 0, readSize);
                        output.flush();
                        mlength += readSize;
                        int progress = mlength;//((int) ((Float.valueOf(mlength) / Float.valueOf(receivelongth)) * 100));

                        Message message = new Message();
                        message.what = 11;
                        message.arg1 = progress;
                        handler.sendMessage(message);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (null != input) input.close();
                        if (null != output) output.close();
                        if (!socket.isClosed()) socket.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
    }
}
